package utils.io;

import org.jetbrains.annotations.NotNull;
import utils.exception.RuntimeIOException;

import java.io.File;
import java.io.IOException;

/**
 * @author Zhou Yifan
 */
public class FileUtils {

    private FileUtils() {
    }

    /**
     * 根据给定的目录名创建目录
     *
     * @param dir 给定目录名
     * @return 布尔值
     */
    public static boolean makeDirectory(String dir) {
        File file = new File(dir);
        return file.mkdirs();
    }

    /**
     * 返回完整的绝对路径
     *
     * @param path 路径
     * @return 字符串
     */
    public static @NotNull String getFullPath(String path) {
        try {
            File file = new File(path);
            return file.getCanonicalPath();
        } catch (IOException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * 返回父目录的路径；
     *
     * @param path 路径
     * @return String
     */
    public static String getParent(String path) {
        File file = new File(path);
        return file.getParent();
    }

    /**
     * 删除文件，此方法调用了 {@link #deleteFile(String, boolean)}
     *
     * @param dir 文件路径
     */
    public static void deleteFile(String dir) {
        deleteFile(dir, false);
    }

    /**
     * 删除文件，此方法调用了 {@link #deleteFile(String, boolean)}
     *
     * @param file 文件对象
     */
    public static void deleteFile(File file) {
        deletePath(file, false);
    }

    /**
     * 删除文件，详细说明参考 {@link #deletePath(File, boolean)}
     *
     * @param dir    文件路径
     * @param silent 是否静默删除
     */
    public static void deleteFile(String dir, boolean silent) {
        File directory = new File(dir);
        deletePath(directory, silent);
    }

    /**
     * 删除文件
     *
     * @param path   如果指定的路径是单个文件，则删除该文件；如果指定路径是目录，则删除该目录及其下的全部文件
     * @param silent 是否静默删除；如果为 true ，则吞噬删除过程中的异常， 意味着方法即便正常返回时也有可能删除不完全
     * @return 如果删除成功，则返回 true； 否则返回 false，或者抛出 {@link RuntimeIOException}
     */
    public static boolean deletePath(@NotNull File path, boolean silent) {
        if (path.isFile()) {
            try {
                path.delete();
                return true;
            } catch (Exception e) {
                if (!silent) {
                    throw new RuntimeIOException(e.getMessage(), e);
                }
            }

            return false;
        }

        // delete dir;
        File[] files = path.listFiles();
        if (files == null) {
            return false;
        }

        for (File f : files) {
            deletePath(f, silent);
        }
        return path.delete();
    }

}
